import 'dart:async';

import 'package:event_bus/event_bus.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_downloader/flutter_downloader.dart';

class CYDownload {
  // 工厂模式
  factory CYDownload() => _getInstance();
  static CYDownload get instance => _getInstance();
  static CYDownload _instance;
  static bool inited = false;

  init() async {
    if(inited != true) {
      inited = true;
      try {
        /// 下载持久化
        // await FlutterDownloader.initialize();
      } catch (e) {
      }
    }
  }

  _download() async {
    await init();
    // 初始化
    FlutterDownloader.registerCallback((id, status, progress) async {
        if(status == DownloadTaskStatus.complete) {
          final tasks = await FlutterDownloader.loadTasksWithRawQuery(query: "SELECT * FROM task WHERE task_id='$id'");
          if(tasks.length>0) {
            eventBus.fire(tasks[0]);
          } else {
            eventBus.fire(DownloadTask(taskId: id, status: DownloadTaskStatus.failed , progress: progress));
          }
          return;
        }
        eventBus.fire(DownloadTask(taskId: id, status: status, progress: progress ));
    });
  }


  CYDownload._internal() {
    _download();
  }
  static CYDownload _getInstance() {
    if (_instance == null) {
      _instance = new CYDownload._internal();
    }
    return _instance;
  }

  EventBus eventBus = new EventBus();

  Future<DownloadTask> download(String source, String path, { ValueChanged<int> onProgress,  bool showNotification = true, bool openFileFromNotification = false,  }) async {
    final taskId = await FlutterDownloader.enqueue(
      url: source,
      savedDir: path,
      showNotification: showNotification,
      openFileFromNotification: openFileFromNotification,
    );
    Completer<DownloadTask> saveTask = Completer<DownloadTask>();

    eventBus.on<DownloadTask>().listen((DownloadTask task) {
      if(saveTask.isCompleted || taskId != task.taskId) return;
      if(onProgress!=null) {
        onProgress(task.progress);
      }
      if(task.status == DownloadTaskStatus.complete) {
         saveTask.complete(task);
      }
      if(
        (
          task.status == DownloadTaskStatus.canceled ||
          task.status == DownloadTaskStatus.failed 
        )
      ) {
        FlutterDownloader.cancel(taskId: taskId);
        saveTask.completeError("用户取消下载或者异常中断");
      }
    });
    return await saveTask.future;
  }
}
